#ifndef SRC_CORE_ASYNC_PACKET_SOCKET_IMPL_H_
#define SRC_CORE_ASYNC_PACKET_SOCKET_IMPL_H_

#include "core/async_packet_socket.h"

namespace vz {

struct PacketHeader {
  uint8 v;
  uint8 z;
  uint16 cmd;
  uint32 data_size;
};

class AsyncPacketSocketImpl : public AsyncPacketSocket {
 public:
  AsyncPacketSocketImpl(AsyncSocket* socket,
                        size_t max_packet_size = DEFAULT_MAX_PACKET_SIZE);
  virtual ~AsyncPacketSocketImpl();

  SocketAddress GetLocalAddress() const;

  SocketAddress GetRemoteAddress() const;

  void SetError(int error);

  int GetError() const;

  int Connect(const SocketAddress &address);

  int SendPacket(int16 cmd, const void *data = NULL, uint32 data_size = 0);

  int Close();

 private:
  Ptr SharedFromThis();

  void OnConnectEvent(AsyncSocket* socket);
  void OnReadEvent(AsyncSocket* socket);
  void OnWriteEvent(AsyncSocket* socket);
  void OnCloseEvent(AsyncSocket* socket, int error);

  void ProcessInput(char * data, size_t* len);
  void AppendToOutBuffer(const void *data, size_t len);
  int FlushOutBuffer();

 private:
  scoped_ptr<AsyncSocket> socket_;
  char* inbuf_, *outbuf_;
  size_t insize_, inpos_, outsize_, outpos_;
};

}  // namespace vz

#endif  // SRC_CORE_ASYNC_PACKET_SOCKET_IMPL_H_



